﻿using System;
using System.Collections.Generic;
using System.Data.Entity;

using System.Linq;
using System.Web.Mvc;

using PagedList;
using SIG.Service;
using SIG.Model;
using AutoMapper;


using SIG.WebMVC.Filters;
using SIG.Model.Enums;
using SIG.ViewModel.Admin;
using SIG.Infrastructure.Configs;
using SIG.ViewModel;
using SIG.Infrastructure.Extensions;
using SIG.Resources.Admin;
using SIG.InputModel.Admin;

namespace SIG.WebMVC.Areas.Admin.Controllers
{

    [SIGAuth]
    public class ProductController : BaseController
    {
      
         private readonly ICategoryService _categoryService;
         private readonly IProductService _productService;
         private readonly IProductPhotoService _productPhotoService;
        private readonly IPageMetaService _pageMetaService;
        private readonly IMapper _mapper;

        public ProductController(ICategoryService categoryService, IProductService productService, IProductPhotoService productPhotoService, IPageMetaService pageMetaService, IMapper mapper)
        {
            _categoryService = categoryService;
            _productService = productService;
            _productPhotoService = productPhotoService;
            _pageMetaService = pageMetaService;
            _mapper = mapper;

        }

        #region 产品分类
      
      [HttpGet]
        public ActionResult Category()
        {

            ViewBag.ModelType = ModelType.PRODUCT;
            ModelType Type = ModelType.PRODUCT; // ToModelType(ref modelType);
            ViewBag.ModelTypeName = Type.DisplayName();
            var categories = _categoryService.GetAllCategories(Type);
            return View(categories);
        }

        [HttpGet]
        public ActionResult CreateCategory()
        {

            ViewBag.ModelType = ModelType.PRODUCT;
            ModelType Type = ModelType.PRODUCT; // ToModelType(ref modelType);

            ViewBag.ModelTypeName = Type.DisplayName();

            Category vCategory = new Category();
            vCategory.Active = true;
            vCategory.Importance = 0;

            GetParentCategories(Type, null);

            return PartialView("_CreateCategory", vCategory);
        }



        [HttpPost]
        public JsonResult CreateCategory([Bind(Include = "Id,Title,Importance,ParentId,Active")]Category category)
        {
            category.ModelType = ModelType.PRODUCT;
            category.IsSys = false;

            if (!ModelState.IsValid)
            {
                AR.Setfailure(GetModelErrorMessage());
                return Json(AR, JsonRequestBehavior.DenyGet);
            }


            _categoryService.Create(category);

            AR.SetSuccess(String.Format(Messages.AlertCreateSuccess, EntityNames.Category));
            return Json(AR, JsonRequestBehavior.DenyGet);

        }


        [HttpGet]
        public ActionResult EditCategory(int id)
        {
            //if (id == null)
            //{
            //    return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            //}


            ViewBag.ModelType = ModelType.PRODUCT;
            ModelType Type = ModelType.PRODUCT; // ToModelType(ref modelType);
            ViewBag.ModelTypeName = Type.DisplayName();

            GetParentCategories(Type, id);

            Category category = _categoryService.GetById(id);

            return PartialView("_EditCategory", category);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]

        public JsonResult EditCategory([Bind(Include = "Id,Title,Importance,ParentId,Active")]Category category)
        {
            category.ModelType = ModelType.PRODUCT;
            category.IsSys = false;

            if (!ModelState.IsValid)
            {
                AR.Setfailure(GetModelErrorMessage());
                return Json(AR, JsonRequestBehavior.DenyGet);
            }


            _categoryService.Update(category);

            AR.SetSuccess(String.Format(Messages.AlertUpdateSuccess, EntityNames.Category));
            return Json(AR, JsonRequestBehavior.DenyGet);

        }

        // DELETE: /User/DeleteSite
        [HttpPost]
        [ValidateAntiForgeryToken]
        public JsonResult DeleteCategory(int id)
        {

            Category vCategory = _categoryService.GetById(id);

            if (vCategory.Products.Any())
            {
                AR.Setfailure("此分类下面还有产品存在，不能删除！");
                return Json(AR, JsonRequestBehavior.DenyGet);
            }

            _categoryService.Delete(vCategory);
            AR.SetSuccess(String.Format(Messages.AlertDeleteSuccess, EntityNames.Category));
            return Json(AR, JsonRequestBehavior.DenyGet);

        }


        [HttpPost]
        [ValidateAntiForgeryToken]
        public JsonResult ActiveCategory(int id)
        {

            var vCategory = _categoryService.GetById(id);
            if (vCategory == null)
            {
                AR.Setfailure(Messages.HttpNotFound);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }

            try
            {
                vCategory.Active = !vCategory.Active;
                _categoryService.Update(vCategory);

                AR.SetSuccess(String.Format(Messages.AlertUpdateSuccess,EntityNames.Category));
                return Json(AR, JsonRequestBehavior.DenyGet);

            }
            catch (Exception ex)
            {
                AR.Setfailure(ex.Message);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }



        }


        private void GetParentCategories(ModelType modelType, int? id)
        {
            var parentCategories = _categoryService.GetAllCategories(modelType);
            if (id > 0)
            {
                parentCategories = parentCategories.Where(c => c.Id != id).ToList();
            }

            var lCategories = parentCategories.Select(r => new SelectListItem()
            {
                Value = r.Id.ToString(),
                Text = r.Title
            }).ToList();

            var emptyItem = new SelectListItem()
            {
                Value = "",
                Text = "--选择父级分类--"
            };

            lCategories.Insert(0, emptyItem);
            ViewBag.ParentCategories = new SelectList(lCategories, "Value", "Text");

        }

        /// <summary>
        /// 获取分类列表
        /// </summary>
        /// <returns></returns>
        public List<SelectListItem> GetCategoryList()
         {
             var OptGroups  = _categoryService.GetAllCategories(ModelType.PRODUCT).ToList();        
            //   lCategories.Insert(0, new SelectListItem { Text = "--按分类过滤--", Value = "" });
             return (from category in OptGroups
                 
                 select new SelectListItem
                 {
                     Text = category.Title,
                     Value = category.Id.ToString()
                     // Selected = (blogId == blog.Id)
                 }).ToList();
         }
        // 二级下拉
        public List<SelectListItem> GetCategoryListWithParent()
        {
            var OptGroups = _categoryService.GetAllCategories(ModelType.PRODUCT).Select(c => new SelectListGroup { Name = c.Title }).ToList();
            var categories = _categoryService.GetCategoriesWithParent(ModelType.PRODUCT);
            //   lCategories.Insert(0, new SelectListItem { Text = "--按分类过滤--", Value = "" });

            return (from category in categories
                    let parId = category.ParentId.ToString()
                    select new SelectListItem
                    {
                        Text = category.Title,
                        Value = category.Id.ToString(),
                        Group = OptGroups.FirstOrDefault(o => o.Name == category.ParentCategoryTitle)
                        // Selected = (blogId == blog.Id)
                    }).ToList();
        }

        //单级下拉
        public List<SelectListItem> GetCategoryList(int catId)
         {
             var OptGroups = _categoryService.GetAllCategories(ModelType.PRODUCT).ToList();            
             List<SelectListItem> lCategories = new List<SelectListItem>();
             foreach (var category in OptGroups)
             {            
                 var sli = new SelectListItem
                 {
                     Text = category.Title,
                     Value = category.Id.ToString(),                 
                     Selected = (catId == category.Id)
                 };

                 lCategories.Add(sli);

             }
             lCategories.Insert(0, new SelectListItem { Text = "--按分类过滤--", Value = "" });

             return lCategories;
         }

        // 带组下拉（二级）
        public List<SelectListItem> GetCategoryListWidthParent(int catId)
        {
            var OptGroups = _categoryService.GetAllCategories(ModelType.PRODUCT).Select(c => new SelectListGroup { Name = c.Title }).ToList();
            var categories = _categoryService.GetCategoriesWithParent(ModelType.PRODUCT);
            List<SelectListItem> lCategories = new List<SelectListItem>();
            foreach (var category in categories)
            {
                var parId = category.ParentId.ToString();
                var sli = new SelectListItem
                {
                    Text = category.Title,
                    Value = category.Id.ToString(),
                    Group = OptGroups.FirstOrDefault(o => o.Name == category.ParentCategoryTitle),
                    Selected = (catId == category.Id)
                };

                lCategories.Add(sli);

            }
            lCategories.Insert(0, new SelectListItem { Text = "--按分类过滤--", Value = "" });

            return lCategories;
        }

        #endregion

        #region  产品

      [HttpGet]
         public ActionResult Index(int? page, int? catId)
         {
             var productsVM = new ProductListVM();

             productsVM.CatId = catId ?? 0;
             productsVM.PageIndex = (page ?? 1) - 1;
             productsVM.PageSize = SettingsManager.Product.PageSize;

             productsVM.Products = _productService.SearchProducts(productsVM.PageIndex, productsVM.PageSize, productsVM.CatId);

             productsVM.TotalCount = _productService.SearchProductsCount(productsVM.CatId);
             productsVM.Categories = GetCategoryList(productsVM.CatId);

             var prosAsIPagedList = new StaticPagedList<Product>(productsVM.Products, productsVM.PageIndex + 1, productsVM.PageSize, productsVM.TotalCount);
             ViewBag.OnePageOfProducts = prosAsIPagedList;

             return View(productsVM);

           
         }



         
         public ActionResult AddProduct()
         {
            ProductPageMetaDTO product = new ProductPageMetaDTO();
             product.Active = true;

          
             ViewBag.Categories = GetCategoryList();
             return PartialView("_AddProduct", product);
         }


         [HttpPost]
         [ValidateAntiForgeryToken]
         public JsonResult AddProduct(ProductPageMetaDTO product)
         {
           

            if (!ModelState.IsValid)
            {
                AR.Setfailure(GetModelErrorMessage());
                return Json(AR, JsonRequestBehavior.DenyGet);

            }

            try
            {
                var newProduct = _mapper.Map<ProductPageMetaDTO, Product>(product);

                var lCategories = (from c in _categoryService.GetAll()
                                   where newProduct.PostCategoryIds.Contains(c.Id.ToString())
                                   select c).ToList();
               
                //var lCategories = (from c in _productService.GetCategories()
                //                       where newProduct.PostCategoryIds.Contains(c.Id.ToString())
                //                       select c).ToList();

                    newProduct.Categories = lCategories;
             
              
                //product.CategoryIds = string.Join(",", product.PostCategoryIds);

                _productService.Create(newProduct);

                if(!string.IsNullOrEmpty(product.Keywords) || !string.IsNullOrEmpty(product.SEODescription))
                {
                    var pageMeta = new PageMeta()
                    {
                        ObjectId = newProduct.Id,
                        Keyword = product.Keywords,
                        Description = product.SEODescription,
                        ModelType = ModelType.PRODUCT
                    };
                    _pageMetaService.Create(pageMeta);
                }

                AR.SetSuccess(String.Format(Messages.AlertCreateSuccess, EntityNames.Product));              
                return Json(AR, JsonRequestBehavior.DenyGet);

            }
            catch (Exception er)
            {
                AR.Setfailure(er.Message);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }



        }

        [HttpGet]
        public ActionResult EditProduct(int id)
        {

            var vProduct = _productService.GetProductByIdWithCategories(id);
            if (vProduct == null)
            {
                AR.Setfailure(Messages.HttpNotFound);
                return Json(AR, JsonRequestBehavior.AllowGet);
            }

            if (vProduct.Categories.Count > 0)
                vProduct.PostCategoryIds = vProduct.Categories.Select(c => c.Id.ToString()).ToArray();

            var editProduct = _mapper.Map<Product, ProductPageMetaDTO>(vProduct);

            var pageMeta = _pageMetaService.GetPageMeta(ModelType.PRODUCT, editProduct.Id);
            if (pageMeta != null)
            {
                editProduct.Keywords = pageMeta.Keyword;
                editProduct.SEODescription = pageMeta.Description;
            }

            ViewBag.Categories = GetCategoryList();
            return PartialView("_EditProduct", editProduct);


        }


        
         [HttpPost]
         [ValidateInput(false)]
         [ValidateAntiForgeryToken]
         public JsonResult EditProduct(ProductPageMetaDTO product)
         {
            
            if (!ModelState.IsValid)
            {
                AR.Setfailure(GetModelErrorMessage());
                return Json(AR, JsonRequestBehavior.DenyGet);

            }
            

            try
            {
                var editProduct = _mapper.Map<ProductPageMetaDTO, Product>(product);               

                //product.CategoryIds = string.Join(",", product.PostCategoryIds);

                _productService.UpdateProductWithCategory(editProduct);

                var pageMeta = _pageMetaService.GetPageMeta(ModelType.PRODUCT, editProduct.Id);
                pageMeta = pageMeta ?? new PageMeta();


                if (!string.IsNullOrEmpty(product.Keywords) || !string.IsNullOrEmpty(product.SEODescription))
                {

                    pageMeta.ObjectId = editProduct.Id;
                    pageMeta.Keyword = product.Keywords;
                    pageMeta.Description = product.SEODescription;
                    pageMeta.ModelType = ModelType.PRODUCT;
                 
                    if(pageMeta.Id >0 )
                    {
                        _pageMetaService.Update(pageMeta);
                    }                       
                    else
                    {                    
                        _pageMetaService.Create(pageMeta);
                    }
                }

                AR.SetSuccess(String.Format(Messages.AlertUpdateSuccess, EntityNames.Product));
                return Json(AR, JsonRequestBehavior.DenyGet);

            }
            catch (Exception er)
            {
                AR.Setfailure(er.Message);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }
                        

         }

            [HttpPost]
         public JsonResult Recommend(int id)
         {

             Product vProduct = _productService.GetById(id);

            if (vProduct == null)
            {
                AR.Setfailure(Messages.HttpNotFound);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }

            try
             {
                
                vProduct.Recommend = !vProduct.Recommend;
                _productService.Update(vProduct);

                AR.SetSuccess(String.Format(Messages.AlertUpdateSuccess, EntityNames.Product));
                return Json(AR, JsonRequestBehavior.DenyGet);
            }
             catch (Exception ex)
             {
                AR.Setfailure(ex.Message);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }
         
         }


        [HttpPost]
        [ValidateAntiForgeryToken]
        public JsonResult Active(int id)
        {

            Product vProduct = _productService.GetById(id);

            try
            {
                vProduct.Active = !vProduct.Active;
                _productService.Update(vProduct);

                AR.SetSuccess(String.Format(Messages.AlertUpdateSuccess, EntityNames.Product));
                return Json(AR, JsonRequestBehavior.DenyGet);

            }
            catch (Exception ex)
            {
                AR.Setfailure(ex.Message);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }

        }



         [HttpPost]
         [ValidateAntiForgeryToken]
         public JsonResult Delete(int id)
         {

             Product vProduct = _productService.GetById(id);

            if (vProduct == null)
            {
                AR.Setfailure(Messages.HttpNotFound);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }
                      
            _productService.Delete(vProduct);

            AR.SetSuccess(String.Format(Messages.AlertDeleteSuccess, EntityNames.Article));
            return Json(AR, JsonRequestBehavior.DenyGet);         

           
         }

        #endregion

        #region 产品图片
         [HttpGet]
         public ActionResult Photos(int productId)
         {
             
             var photo = new ProductPhoto
             {
                 ProductId = productId
             };
          
             return PartialView("_uploadPhotos",photo);
         }
        [HttpGet]
        [AllowAnonymous]
        public ActionResult GetPhotos(int productId)
        {
           
           var  Photos = _productPhotoService.GetPhotos(productId);
           return PartialView("_Photos", Photos);
        }


        [HttpPost]       
         public ActionResult AddPhoto(ProductPhoto photo)
         {
            AR.Data = photo.ProductId;
            //photo.AddedDate = DateTime.Now;
            //photo.AddedBy = Site.CurrentUserName;
            if (!ModelState.IsValid)
            {
                AR.Setfailure(GetModelErrorMessage());
                return Json(AR, JsonRequestBehavior.DenyGet);
            }
            
            _productPhotoService.Create(photo);
           
            AR.SetSuccess(String.Format(Messages.AlertUpdateSuccess, EntityNames.ProductPhoto));
            return Json(AR, JsonRequestBehavior.DenyGet);            

         }

         // DELETE: /Product/DeletePhoto
         [HttpPost]      
         public JsonResult DeletePhoto(int id)
         {

             var photo = _productPhotoService.GetById(id);
            AR.Data = photo.ProductId;
             if (photo == null)
            {
                AR.Setfailure(Messages.HttpNotFound);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }               

            _productPhotoService.Delete(photo);
            AR.SetSuccess(String.Format(Messages.AlertDeleteSuccess, EntityNames.ProductPhoto));
            return Json(AR, JsonRequestBehavior.DenyGet);
        }


        #endregion
    }
}
